import os
import json
import shutil
from datetime import datetime
from typing import List, Dict, Optional
from pathlib import Path

from models import ConversationSession, UserStats, db
from config import Config


class ConversationFileService:
    """对话文件管理服务 - 基于会话的对话记录"""
    
    def __init__(self):
        # 基础存储目录
        self.base_storage_dir = getattr(Config, 'CONVERSATION_STORAGE_DIR', 'conversation_data')
        self.ensure_base_directory()
    
    def ensure_base_directory(self):
        """确保基础存储目录存在"""
        if not os.path.exists(self.base_storage_dir):
            os.makedirs(self.base_storage_dir, exist_ok=True)
    
    def get_user_directory(self, user_id: int) -> str:
        """获取用户专属目录路径"""
        user_dir = os.path.join(self.base_storage_dir, f'user_{user_id}')
        if not os.path.exists(user_dir):
            os.makedirs(user_dir, exist_ok=True)
        return user_dir
    
    def create_session_directory(self, user_id: int, session_id: str) -> tuple[str, str]:
        """为会话创建目录
        按照用户要求的结构：用户id/session_id
        
        Returns:
            tuple: (session_dir_path, timestamp_folder_name)
        """
        user_dir = self.get_user_directory(user_id)
        
        # 生成时间戳文件夹名
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        timestamp_folder = f'{timestamp}_{session_id}'
        
        session_dir = os.path.join(user_dir, f'session_{session_id}')
        os.makedirs(session_dir, exist_ok=True)
        
        return session_dir, timestamp_folder
    
    def save_query_file(self, conversation_dir: str, query_text: str) -> str:
        """保存查询文件"""
        query_file = os.path.join(conversation_dir, 'query.txt')
        with open(query_file, 'w', encoding='utf-8') as f:
            f.write(query_text)
        return query_file
    
    def save_response_file(self, conversation_dir: str, response_text: str) -> str:
        """保存响应文件"""
        response_file = os.path.join(conversation_dir, 'response.txt')
        with open(response_file, 'w', encoding='utf-8') as f:
            f.write(response_text)
        return response_file
    
    def save_log_file(self, conversation_dir: str, log_data: List[Dict]) -> str:
        """保存日志文件"""
        log_file = os.path.join(conversation_dir, 'execution_log.json')
        with open(log_file, 'w', encoding='utf-8') as f:
            json.dump(log_data, f, ensure_ascii=False, indent=2)
        return log_file
    
    def save_metadata_file(self, conversation_dir: str, metadata: Dict) -> str:
        """保存元数据文件"""
        metadata_file = os.path.join(conversation_dir, 'metadata.json')
        with open(metadata_file, 'w', encoding='utf-8') as f:
            json.dump(metadata, f, ensure_ascii=False, indent=2)
        return metadata_file
    
    def get_file_size(self, file_path: str) -> int:
        """获取文件大小"""
        try:
            return os.path.getsize(file_path)
        except OSError:
            return 0
    
    def get_or_create_session(self, user_id: int, session_id: str) -> ConversationSession:
        """获取或创建会话记录"""
        try:
            # 先尝试获取现有会话
            session = ConversationSession.query.filter_by(
                user_id=user_id, 
                session_id=session_id
            ).first()
            
            if session:
                return session
            
            # 创建新会话
            session_dir, timestamp_folder = self.create_session_directory(user_id, session_id)
            
            session = ConversationSession(
                user_id=user_id,
                session_id=session_id,
                conversation_dir=session_dir,
                timestamp_folder=timestamp_folder,
                conversation_file=os.path.join(session_dir, "conversation.jsonl"),
                metadata_file=os.path.join(session_dir, "metadata.json")
            )
            
            db.session.add(session)
            db.session.flush()  # 确保时间字段被设置
            
            # 初始化元数据文件
            self._init_metadata(session)
            
            db.session.commit()
            
            return session
            
        except Exception as e:
            db.session.rollback()
            raise Exception(f"创建会话记录失败: {str(e)}")
    
    def add_message_to_session(self, user_id: int, session_id: str, 
                              request_id: str, query_text: str, 
                              response_text: str, log_data: List[Dict] = None,
                              tokens: int = 0, cost: float = 0.0) -> ConversationSession:
        """向会话添加消息"""
        try:
            # 获取或创建会话
            session = self.get_or_create_session(user_id, session_id)
            
            # 准备消息数据
            message_data = {
                'request_id': request_id,
                'timestamp': datetime.now().isoformat(),
                'query': query_text,
                'response': response_text,
                'log_data': log_data,
                'tokens': tokens,
                'cost': cost
            }
            
            # 追加到对话文件
            self._append_to_conversation_file(session, message_data)
            
            # 更新元数据
            self._update_metadata(session, message_data)
            
            # 更新数据库中的会话统计信息
            session.message_count += 1
            session.total_tokens += tokens
            session.total_cost += cost
            session.last_message_at = datetime.utcnow()
            session.updated_at = datetime.utcnow()
            
            # 如果没有标题，从第一个查询生成
            if not session.title and query_text:
                session.title = query_text[:50] + ('...' if len(query_text) > 50 else '')
            
            # 提交数据库更改
            db.session.commit()
            
            return session
            
        except Exception as e:
            db.session.rollback()
            raise Exception(f"添加消息到会话失败: {str(e)}")
    
    def save_execution_process(self, session_id: str, query_id: str, execution_data: Dict):
        """保存执行过程数据，供前端回显使用
        
        Args:
            session_id: 会话ID
            query_id: 查询ID
            execution_data: 执行过程数据，包含中间步骤和最终结果
        """
        try:
            # 获取会话记录
            session = ConversationSession.query.filter_by(session_id=session_id).first()
            if not session:
                raise Exception(f"会话不存在: {session_id}")
            
            # 创建执行过程文件路径
            execution_dir = os.path.join(session.conversation_dir, 'executions')
            os.makedirs(execution_dir, exist_ok=True)
            
            execution_file = os.path.join(execution_dir, f'execution_{query_id}.json')
            
            # 增强执行数据结构，确保包含完整的中间步骤
            enhanced_execution_data = {
                'query_id': query_id,
                'session_id': session_id,
                'timestamp': execution_data.get('timestamp', datetime.now().isoformat()),
                'query_text': execution_data.get('query_text', ''),
                'final_response': execution_data.get('final_response', ''),
                'execution_time': execution_data.get('execution_time', 0),
                'total_cost': execution_data.get('total_cost', 0.0),
                'step_count': len(execution_data.get('intermediate_steps', [])),
                'intermediate_steps': execution_data.get('intermediate_steps', []),
                'log_data': execution_data.get('log_data', []),
                'all_outputs': execution_data.get('all_outputs', []),
                'agent_output': execution_data.get('agent_output', ''),
                'error_info': execution_data.get('error_info', None),
                'metadata': {
                    'saved_at': datetime.now().isoformat(),
                    'version': '2.0',  # 标记为增强版本
                    'has_intermediate_steps': len(execution_data.get('intermediate_steps', [])) > 0
                }
            }
            
            # 保存执行过程数据
            with open(execution_file, 'w', encoding='utf-8') as f:
                json.dump(enhanced_execution_data, f, ensure_ascii=False, indent=2)
            
            # 同时保存中间步骤的详细日志文件（JSONL格式，便于逐步读取）
            if enhanced_execution_data['intermediate_steps']:
                steps_file = os.path.join(execution_dir, f'steps_{query_id}.jsonl')
                with open(steps_file, 'w', encoding='utf-8') as f:
                    for step in enhanced_execution_data['intermediate_steps']:
                        json.dump(step, f, ensure_ascii=False)
                        f.write('\n')
            
            # 更新会话的执行过程文件列表
            if not hasattr(session, 'execution_files') or session.execution_files is None:
                session.execution_files = []
            
            execution_info = {
                'query_id': query_id,
                'file_path': execution_file,
                'steps_file': os.path.join(execution_dir, f'steps_{query_id}.jsonl') if enhanced_execution_data['intermediate_steps'] else None,
                'timestamp': enhanced_execution_data['timestamp'],
                'step_count': enhanced_execution_data['step_count'],
                'has_intermediate_steps': enhanced_execution_data['metadata']['has_intermediate_steps'],
                'execution_time': enhanced_execution_data['execution_time'],
                'total_cost': enhanced_execution_data['total_cost']
            }
            
            # 检查是否已存在该查询的执行记录，如果存在则更新
            existing_index = None
            for i, exec_info in enumerate(session.execution_files):
                if exec_info.get('query_id') == query_id:
                    existing_index = i
                    break
            
            if existing_index is not None:
                session.execution_files[existing_index] = execution_info
            else:
                session.execution_files.append(execution_info)
            
            # 标记字段已修改
            from sqlalchemy.orm.attributes import flag_modified
            flag_modified(session, 'execution_files')
            
            db.session.commit()
            
            return execution_file
            
        except Exception as e:
             db.session.rollback()
             raise Exception(f"保存执行过程数据失败: {str(e)}")
    
    def save_intermediate_step(self, session_id: str, query_id: str, step_data: Dict, step_index: int = None):
        """保存单个中间执行步骤，用于流式处理中的实时保存
        
        Args:
            session_id: 会话ID
            query_id: 查询ID
            step_data: 单个步骤数据
            step_index: 步骤索引（可选）
        """
        try:
            # 获取会话记录
            session = ConversationSession.query.filter_by(session_id=session_id).first()
            if not session:
                raise Exception(f"会话不存在: {session_id}")
            
            # 创建执行过程文件路径
            execution_dir = os.path.join(session.conversation_dir, 'executions')
            os.makedirs(execution_dir, exist_ok=True)
            
            # 中间步骤文件路径
            steps_file = os.path.join(execution_dir, f'steps_{query_id}.jsonl')
            
            # 增强步骤数据
            enhanced_step_data = {
                'step_index': step_index,
                'timestamp': datetime.now().isoformat(),
                'query_id': query_id,
                'session_id': session_id,
                'step_type': step_data.get('step_type', 'unknown'),
                'content': step_data.get('content', ''),
                'formatted_output': step_data.get('formatted_output', ''),
                'raw_data': step_data.get('raw_data', {}),
                'tool_calls': step_data.get('tool_calls', []),
                'error': step_data.get('error', None),
                'metadata': step_data.get('metadata', {})
            }
            
            # 追加到步骤文件（JSONL格式）
            with open(steps_file, 'a', encoding='utf-8') as f:
                json.dump(enhanced_step_data, f, ensure_ascii=False)
                f.write('\n')
            
            return steps_file
            
        except Exception as e:
            # 中间步骤保存失败不应该影响主流程，只记录错误
            print(f"保存中间步骤失败: {str(e)}")
            return None
    
    def get_execution_steps(self, session_id: str, query_id: str) -> List[Dict]:
        """获取查询的所有执行步骤
        
        Args:
            session_id: 会话ID
            query_id: 查询ID
            
        Returns:
            List[Dict]: 执行步骤列表
        """
        try:
            # 获取会话记录
            session = ConversationSession.query.filter_by(session_id=session_id).first()
            if not session:
                return []
            
            # 步骤文件路径
            execution_dir = os.path.join(session.conversation_dir, 'executions')
            steps_file = os.path.join(execution_dir, f'steps_{query_id}.jsonl')
            
            if not os.path.exists(steps_file):
                return []
            
            steps = []
            with open(steps_file, 'r', encoding='utf-8') as f:
                for line in f:
                    if line.strip():
                        step = json.loads(line)
                        steps.append(step)
            
            return steps
            
        except Exception as e:
            print(f"读取执行步骤失败: {str(e)}")
            return []
    
    def get_execution_process(self, session_id: str, query_id: str) -> Optional[Dict]:
        """获取查询的完整执行过程数据
        
        Args:
            session_id: 会话ID
            query_id: 查询ID
            
        Returns:
            Dict: 执行过程数据，如果不存在返回None
        """
        try:
            # 获取会话记录
            session = ConversationSession.query.filter_by(session_id=session_id).first()
            if not session:
                return None
            
            # 执行过程文件路径
            execution_dir = os.path.join(session.conversation_dir, 'executions')
            execution_file = os.path.join(execution_dir, f'execution_{query_id}.json')
            
            if not os.path.exists(execution_file):
                return None
            
            # 读取执行过程数据
            with open(execution_file, 'r', encoding='utf-8') as f:
                execution_data = json.load(f)
            
            # 同时加载详细的执行步骤数据（从steps_文件）
            steps_file = os.path.join(execution_dir, f'steps_{query_id}.jsonl')
            if os.path.exists(steps_file):
                detailed_steps = []
                with open(steps_file, 'r', encoding='utf-8') as f:
                    for line in f:
                        if line.strip():
                            step = json.loads(line)
                            detailed_steps.append(step)
                
                # 将详细步骤数据合并到执行数据中
                if detailed_steps:
                    execution_data['detailed_steps'] = detailed_steps
                    execution_data['detailed_step_count'] = len(detailed_steps)
                    print(f"加载了 {len(detailed_steps)} 个详细执行步骤")
            
            return execution_data
            
        except Exception as e:
            print(f"读取执行过程数据失败: {str(e)}")
            return None
    
    def archive_downloaded_files(self, session_id: str, query_id: str, download_dir: str):
        """归档下载的文件到对话目录中
        
        Args:
            session_id: 会话ID
            query_id: 查询ID
            download_dir: 下载文件所在目录
        
        Returns:
            list: 归档的文件信息列表
        """
        try:
            # 获取会话记录
            session = ConversationSession.query.filter_by(session_id=session_id).first()
            if not session:
                raise Exception(f"会话不存在: {session_id}")
            
            # 创建下载文件归档目录
            downloads_dir = os.path.join(session.conversation_dir, 'downloads', f'query_{query_id}')
            os.makedirs(downloads_dir, exist_ok=True)
            
            archived_files = []
            
            # 检查下载目录是否存在
            if not os.path.exists(download_dir):
                return archived_files
            
            # 遍历下载目录中的所有文件
            for root, dirs, files in os.walk(download_dir):
                for file in files:
                    source_path = os.path.join(root, file)
                    
                    # 计算相对路径以保持目录结构
                    rel_path = os.path.relpath(source_path, download_dir)
                    dest_path = os.path.join(downloads_dir, rel_path)
                    
                    # 确保目标目录存在
                    os.makedirs(os.path.dirname(dest_path), exist_ok=True)
                    
                    # 复制文件到归档目录
                    shutil.copy2(source_path, dest_path)
                    
                    # 记录文件信息
                    file_info = {
                        'name': file,
                        'original_path': source_path,
                        'archived_path': dest_path,
                        'relative_path': rel_path,
                        'size': os.path.getsize(dest_path),
                        'archived_at': datetime.now().isoformat()
                    }
                    archived_files.append(file_info)
            
            # 更新会话的下载文件记录
            if not hasattr(session, 'download_files') or session.download_files is None:
                session.download_files = []
            
            download_record = {
                'query_id': query_id,
                'download_dir': downloads_dir,
                'files': archived_files,
                'file_count': len(archived_files),
                'total_size': sum(f['size'] for f in archived_files),
                'archived_at': datetime.now().isoformat()
            }
            
            # 检查是否已存在该查询的下载记录，如果存在则更新
            existing_index = None
            for i, download_info in enumerate(session.download_files):
                if download_info.get('query_id') == query_id:
                    existing_index = i
                    break
            
            if existing_index is not None:
                session.download_files[existing_index] = download_record
            else:
                session.download_files.append(download_record)
            
            # 标记字段已修改
            from sqlalchemy.orm.attributes import flag_modified
            flag_modified(session, 'download_files')
            
            db.session.commit()
            
            return archived_files
            
        except Exception as e:
            db.session.rollback()
            raise Exception(f"归档下载文件失败: {str(e)}")
    
    def _init_metadata(self, session: ConversationSession):
        """初始化元数据文件"""
        # 确保元数据文件所在目录存在
        metadata_dir = os.path.dirname(session.metadata_file)
        os.makedirs(metadata_dir, exist_ok=True)
        
        now = datetime.now()
        metadata = {
            'session_id': session.session_id,
            'user_id': session.user_id,
            'created_at': session.created_at.isoformat() if session.created_at else now.isoformat(),
            'updated_at': session.updated_at.isoformat() if session.updated_at else now.isoformat(),
            'message_count': 0,
            'total_tokens': 0,
            'total_cost': 0.0,
            'messages': []
        }
        
        with open(session.metadata_file, 'w', encoding='utf-8') as f:
            json.dump(metadata, f, ensure_ascii=False, indent=2)
    
    def _append_to_conversation_file(self, session: ConversationSession, message_data: Dict):
        """追加消息到对话文件"""
        # 确保对话文件所在目录存在
        conversation_dir = os.path.dirname(session.conversation_file)
        os.makedirs(conversation_dir, exist_ok=True)
        
        # 使用JSONL格式，每行一个JSON对象
        with open(session.conversation_file, 'a', encoding='utf-8') as f:
            json.dump(message_data, f, ensure_ascii=False)
            f.write('\n')
    
    def _update_metadata(self, session: ConversationSession, message_data: Dict):
        """更新元数据文件"""
        try:
            # 确保元数据文件所在目录存在
            metadata_dir = os.path.dirname(session.metadata_file)
            os.makedirs(metadata_dir, exist_ok=True)
            
            # 读取现有元数据，如果文件不存在则创建默认元数据
            if os.path.exists(session.metadata_file):
                with open(session.metadata_file, 'r', encoding='utf-8') as f:
                    metadata = json.load(f)
            else:
                # 创建默认元数据
                now = datetime.now()
                metadata = {
                    'session_id': session.session_id,
                    'user_id': session.user_id,
                    'created_at': session.created_at.isoformat() if session.created_at else now.isoformat(),
                    'updated_at': now.isoformat(),
                    'message_count': 0,
                    'total_tokens': 0,
                    'total_cost': 0.0,
                    'messages': []
                }
            
            # 更新统计信息
            metadata['message_count'] += 1
            metadata['total_tokens'] += message_data.get('tokens', 0)
            metadata['total_cost'] += message_data.get('cost', 0.0)
            metadata['updated_at'] = datetime.now().isoformat()
            metadata['last_message_at'] = message_data['timestamp']
            
            # 添加消息摘要到元数据
            message_summary = {
                'request_id': message_data['request_id'],
                'timestamp': message_data['timestamp'],
                'query_preview': message_data['query'][:100] + ('...' if len(message_data['query']) > 100 else ''),
                'response_preview': message_data['response'][:100] + ('...' if len(message_data['response']) > 100 else ''),
                'tokens': message_data.get('tokens', 0),
                'cost': message_data.get('cost', 0.0)
            }
            metadata['messages'].append(message_summary)
            
            # 写回文件
            with open(session.metadata_file, 'w', encoding='utf-8') as f:
                json.dump(metadata, f, ensure_ascii=False, indent=2)
                
        except Exception as e:
            print(f"更新元数据失败: {e}")
    
    def create_conversation_record(self, user_id: int, request_id: int, 
                                 query_text: str, response_text: str = None, 
                                 log_data: List[Dict] = None, session_id: str = None,
                                 tokens: int = 0, cost: float = 0.0) -> ConversationSession:
        """创建对话记录
        
        Args:
            user_id: 用户ID
            request_id: 请求ID
            query_text: 查询文本
            response_text: 响应文本
            log_data: 日志数据
            session_id: 会话ID（优先使用此参数）
            tokens: token数量
            cost: 费用
        """
        # 优先使用传入的session_id，其次从log_data中获取，最后使用request_id
        if not session_id:
            session_id = log_data[0].get('session_id', str(request_id)) if log_data else str(request_id)
        
        return self.add_message_to_session(
            user_id=user_id,
            session_id=session_id,
            request_id=str(request_id),
            query_text=query_text,
            response_text=response_text or '',
            log_data=log_data,
            tokens=tokens,
            cost=cost
        )
    
    def update_conversation_record(self, conversation_file: ConversationSession, 
                                 response_text: str = None, log_data: List[Dict] = None):
        """更新对话记录"""
        conversation_dir = conversation_file.conversation_dir
        
        # 更新响应文件
        if response_text:
            response_file = self.save_response_file(conversation_dir, response_text)
            response_size = self.get_file_size(response_file)
            
            # 检查是否已存在响应文件记录
            existing_response = False
            for file_info in conversation_file.files or []:
                if file_info['name'] == 'response.txt':
                    file_info['path'] = response_file
                    file_info['size'] = response_size
                    existing_response = True
                    break
            
            if not existing_response:
                conversation_file.add_file('response.txt', response_file, 'response', response_size)
            
            conversation_file.response_summary = response_text[:200] + '...' if len(response_text) > 200 else response_text
        
        # 更新日志文件
        if log_data:
            log_file = self.save_log_file(conversation_dir, log_data)
            log_size = self.get_file_size(log_file)
            
            # 检查是否已存在日志文件记录
            existing_log = False
            for file_info in conversation_file.files or []:
                if file_info['name'] == 'execution_log.json':
                    file_info['path'] = log_file
                    file_info['size'] = log_size
                    existing_log = True
                    break
            
            if not existing_log:
                conversation_file.add_file('execution_log.json', log_file, 'log', log_size)
        
        # 更新元数据
        metadata = {
            'user_id': conversation_file.user_id,
            'request_id': conversation_file.request_id,
            'created_at': conversation_file.created_at.isoformat(),
            'updated_at': datetime.now().isoformat(),
            'query_length': len(conversation_file.query_summary) if conversation_file.query_summary else 0,
            'response_length': len(response_text) if response_text else 0,
            'log_entries': len(log_data) if log_data else 0
        }
        metadata_file = self.save_metadata_file(conversation_dir, metadata)
        
        db.session.commit()
    
    def get_user_conversations(self, user_id: int, limit: int = 50, offset: int = 0) -> List[ConversationSession]:
        """获取用户的会话记录列表"""
        return ConversationSession.query.filter_by(user_id=user_id)\
            .order_by(ConversationSession.created_at.desc())\
            .limit(limit).offset(offset).all()
    
    def get_conversation_by_id(self, conversation_id: int, user_id: int = None) -> Optional[ConversationSession]:
        """根据ID获取会话记录"""
        query = ConversationSession.query.filter_by(id=conversation_id)
        if user_id:
            query = query.filter_by(user_id=user_id)
        return query.first()
    
    def delete_conversation(self, conversation_id: int, user_id: int = None) -> bool:
        """删除对话记录及其文件"""
        conversation = self.get_conversation_by_id(conversation_id, user_id)
        if not conversation:
            return False
        
        # 删除文件目录
        try:
            if os.path.exists(conversation.conversation_dir):
                shutil.rmtree(conversation.conversation_dir)
        except OSError:
            pass  # 文件删除失败不影响数据库记录删除
        
        # 删除数据库记录
        db.session.delete(conversation)
        db.session.commit()
        
        return True
    
    def create_download_archive(self, user_id: int, conversation_ids: List[int] = None) -> str:
        """创建下载归档文件"""
        import zipfile
        
        # 获取要打包的对话
        if conversation_ids:
            conversations = ConversationSession.query.filter(
                ConversationSession.id.in_(conversation_ids),
                ConversationSession.user_id == user_id
            ).all()
        else:
            conversations = self.get_user_conversations(user_id, limit=1000)
        
        if not conversations:
            return None
        
        # 在用户目录下创建downloads子目录
        user_dir = self.get_user_directory(user_id)
        downloads_dir = os.path.join(user_dir, 'downloads')
        os.makedirs(downloads_dir, exist_ok=True)
        
        # 创建zip文件在用户的downloads目录中
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        zip_filename = f'conversations_user_{user_id}_{timestamp}.zip'
        zip_path = os.path.join(downloads_dir, zip_filename)
        
        with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
            for conversation in conversations:
                if os.path.exists(conversation.conversation_dir):
                    # 添加整个对话目录到zip
                    for root, dirs, files in os.walk(conversation.conversation_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            # 在zip中的相对路径
                            arcname = os.path.join(
                                conversation.timestamp_folder,
                                os.path.relpath(file_path, conversation.conversation_dir)
                            )
                            zipf.write(file_path, arcname)
        
        return zip_path

    def get_conversation_content(self, conversation_id: int, user_id: int = None) -> Dict:
        """获取对话的完整内容"""
        conversation = self.get_conversation_by_id(conversation_id, user_id)
        if not conversation:
            return None
        
        content = {
            'id': conversation.id,
            'session_id': conversation.session_id,
            'timestamp_folder': conversation.timestamp_folder,
            'created_at': conversation.created_at.isoformat(),
            'query_text': '',
            'response_text': '',
            'log_data': []
        }
        
        # 优先读取对话文件 (新格式)
        conversation_file = os.path.join(conversation.conversation_dir, 'conversation.jsonl')
        if os.path.exists(conversation_file):
            try:
                messages = []
                latest_query = ''
                latest_response = ''
                
                with open(conversation_file, 'r', encoding='utf-8') as f:
                    for line in f:
                        if line.strip():
                            message = json.loads(line)
                            messages.append(message)
                            # 获取最新的query和response（用于兼容性）
                            if 'query' in message:
                                latest_query = message['query']
                            if 'response' in message:
                                latest_response = message['response']
                
                content['log_data'] = messages
                # 只有在没有消息时才设置空值，否则保持最新消息用于兼容性
                if messages:
                    content['query_text'] = latest_query
                    content['response_text'] = latest_response
                
            except Exception as e:
                print(f"读取对话文件失败: {e}")
        
        # 如果conversation.jsonl不存在或为空，则尝试读取旧格式文件
        if not content['query_text'] and not content['response_text']:
            # 读取查询文件
            query_file = os.path.join(conversation.conversation_dir, 'query.txt')
            if os.path.exists(query_file):
                try:
                    with open(query_file, 'r', encoding='utf-8') as f:
                        content['query_text'] = f.read()
                except Exception as e:
                    print(f"读取查询文件失败: {e}")
            
            # 读取响应文件
            response_file = os.path.join(conversation.conversation_dir, 'response.txt')
            if os.path.exists(response_file):
                try:
                    with open(response_file, 'r', encoding='utf-8') as f:
                        content['response_text'] = f.read()
                except Exception as e:
                    print(f"读取响应文件失败: {e}")
        
        return content
    
    def get_storage_stats(self, user_id: int = None) -> Dict:
        """获取存储统计信息"""
        query = ConversationSession.query
        if user_id:
            query = query.filter_by(user_id=user_id)
        
        sessions = query.all()
        
        total_size = sum(self._get_session_size(session) for session in sessions)
        total_files = len(sessions) * 2  # conversation.jsonl + metadata.json
        total_conversations = len(sessions)
        
        return {
            'total_conversations': total_conversations,
            'total_files': total_files,
            'total_size': total_size,
            'total_size_mb': round(total_size / (1024 * 1024), 2),
            'avg_size_per_conversation': round(total_size / total_conversations, 2) if total_conversations > 0 else 0
        }
    
    def _get_session_size(self, session: ConversationSession) -> int:
        """获取会话文件总大小"""
        total_size = 0
        if os.path.exists(session.conversation_file):
            total_size += self.get_file_size(session.conversation_file)
        if os.path.exists(session.metadata_file):
            total_size += self.get_file_size(session.metadata_file)
        return total_size